Read in Script
source("Safegraph_Script.R")
NAs introduced by coercion
rm(list=ls()[! ls() %in% c("rural_ipums","ruca", "subset_glass",
"poverty_ipums", "pct_chg_aug",
"industry_ipums", "aug_combined",
"buffer1_vec","buffer2_perim_vec",
"buffer2_vec", "cf_bf1", "cf_bf2", "gfperimvec",
"not_zcta", "rural_ruca",
'%notin%', 'pp1', 'pp2', 'aug_combined', 'com')])
Read in Spatial Plots
plot.new()
rasterImage(pp1,0,0,1,1)

plot.new()
rasterImage(pp2,0,0,1,1)

Initially a single 20-acre brush fire, it rapidly grew and merged with two smaller fires that expanded to 11,000 acres during the night of September 27 into September 28.
The Glass Fire was fully contained on October 20, 2020, after burning over 67,484 acres and destroying 1,555 structures, including 308 homes and 343 commercial buildings in Napa County, as well as 334 homes in Sonoma County
Data Tables (Descriptives)
Using shape files from the GlassFire, 10 km buffers were used to create the first buffer (BF1), 10km surrounding BF1 creates the second buffer (BF2).
Each perimeter has unique ZCTA that is exclusive to their perimeter.
DT::datatable(com %>%
filter(june != 'June') %>%
mutate(new_date = as.POSIXct(strptime(date_range_start, "%Y-%m-%d"))) %>%
mutate(week = as_date(new_date)) %>%
group_by(city, zcta, week, fire_cat,
Poverty_Dummy_75, Agr_Dummy_75,
Rural_Dummy_R) %>%
summarize(sum_visit = sum(raw_visit_counts), .groups = 'drop'),
caption = 'Descriptive Statistics of August Mobility',
filter = "top",
extensions = c("SearchPanes", "Select", "Buttons"),
options = list(dom = "Btip",buttons = list("searchPanes")))
DT::datatable(com %>%
filter(june == 'June') %>%
mutate(new_date = as.POSIXct(strptime(date_range_start, "%Y-%m-%d"))) %>%
mutate(week = as_date(new_date)) %>%
group_by(city, zcta, week, fire_cat,
Poverty_Dummy_75, Agr_Dummy_75,
Rural_Dummy_R) %>%
summarize(sum_visit = sum(raw_visit_counts), .groups = 'drop'),
caption = 'Descriptive Statistics of June Mobility',
filter = "top",
extensions = c("SearchPanes", "Select", "Buttons"),
options = list(dom = "Btip",buttons = list("searchPanes")))
Visualizations
Percent Change Using Fire Category and June as Baseline
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta,fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups = 'drop') %>%
ggplot(data =., aes(x = week, y = med, group = zcta)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=fire_cat), alpha = 0.2) +
geom_point(aes(colour = fire_cat), alpha = 0.8) +
ylim(-50,200) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change (Divide by 100)") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = -50.00, ymax = 150.00 ,
alpha = 0, color= "orange") +
ggtitle("Percent Change Mobility by Fire Category")

When looking at mobility: + Week of June 6, 2020 to the week of June 22, 2020 is used as a baseline + Percent change is calculated by week to week in each consecutive week in June + The median of percent change is then grouped by fire category in June and is then officially the baseline for August mobility + Then the percent change of August is then used for each consecutive week in August (August 31 - October 12) + A calculation of percent change is taken by using the weekly percentage change for August in relation to the fire category median percent change.
| GF |
0.02 |
| BF1 |
0.03 |
| BF2 |
0.04 |
Percent Change of Mobility by Rural/ Fire Category and June as Baseline
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta,Rural_Dummy_R, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups = 'drop') %>%
ggplot(data =., aes(x = week, y = med, group = zcta)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Rural_Dummy_R), alpha = 0.2) +
geom_point(aes(colour = Rural_Dummy_R), alpha = 0.8) +
ylim(-50,200) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change (Divide by 100") +
facet_wrap(vars(fire_cat), nrow = 3) +
ggtitle("Percent Change Mobility by Fire Category and Rural")

pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta, fire_cat) %>%
group_by(Rural_Dummy_R, week, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Rural_Dummy_R)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Rural_Dummy_R)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) + facet_wrap(vars(fire_cat), nrow = 3) +ylim(-50,50) +
ggtitle("Percent Change Mobility by Fire Category and Rural (Collapsed)") +
labs(x="Date", y="Median Percent Change (Divide by 100")

pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta) %>%
group_by(Rural_Dummy_R, week, fire_cat) %>%
filter(fire_cat == 'GF') %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Rural_Dummy_R)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Rural_Dummy_R)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change (Divide by 100)") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = -20, ymax = 60 ,
alpha = 0, color= "orange") +
ggtitle("Median Raw Visits by Date (GF/Collapsed)")

Percent Change of Mobility by Agriculture/ Fire Category and June as Baseline
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta,Agr_Dummy_75, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups = 'drop') %>%
ggplot(data =., aes(x = week, y = med, group = zcta)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Agr_Dummy_75), alpha = 0.2) +
geom_point(aes(colour = Agr_Dummy_75), alpha = 0.8) +
ylim(-50,200) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change (Divide by 100)") +
facet_wrap(vars(fire_cat), nrow = 3) +
ggtitle("Percent Change Mobility by Fire Category and Agr Industry")

# Agriculture BY Fire Cat
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta, fire_cat) %>%
group_by(Agr_Dummy_75, week, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Agr_Dummy_75)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Agr_Dummy_75)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) + facet_wrap(vars(fire_cat), nrow = 3) +ylim(-50,50) +
ggtitle("Percent Change Mobility by Fire Category and Agr (Collapsed)") +
labs(x="Date", y="Median Percent Change (Divide by 100)")

pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta) %>%
group_by(Agr_Dummy_75, week, fire_cat) %>%
filter(fire_cat == 'GF') %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Agr_Dummy_75)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Agr_Dummy_75)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change (Divide by 100)") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = -20, ymax = 60 ,
alpha = 0, color= "orange")+
ggtitle("Median Raw Visits by Date (GF/Collapsed)")

Percent Change of Mobility by Poverty/ Fire Category and June as Baseline
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta,Poverty_Dummy_75, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups = 'drop') %>%
ggplot(data =., aes(x = week, y = med, group = zcta)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Poverty_Dummy_75), alpha = 0.2) +
geom_point(aes(colour = Poverty_Dummy_75), alpha = 0.8) +
ylim(-50,200) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change") + facet_wrap(vars(fire_cat), nrow = 3)

# Poverty BY Fire Cat
pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta, fire_cat) %>%
group_by(Poverty_Dummy_75, week, fire_cat) %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Poverty_Dummy_75)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Poverty_Dummy_75)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) + facet_wrap(vars(fire_cat), nrow = 3) + ylim(-75,100)

pct_chg_aug %>%
na.omit() %>%
group_by(week,zcta) %>%
group_by(Poverty_Dummy_75, week, fire_cat) %>%
filter(fire_cat == 'GF') %>%
summarize(med = median(pct_chg_mon_f), .groups ='drop') %>%
ggplot(data =., aes(x = week, y = med, group = Poverty_Dummy_75)) +
scale_color_manual(values=c('Blue','Green', 'Red')) +
geom_line(aes(colour=Poverty_Dummy_75)) +
geom_point(size = 2) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +# week of Oct 12
theme(axis.text.x = element_text(angle = 0)) +
labs(x="Date", y="Median Percent Change") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = -25, ymax = 60 ,
alpha = 0, color= "orange")

ggtitle("Median Raw Visits by Date")
$title
[1] "Median Raw Visits by Date"
attr(,"class")
[1] "labels"
Looking at PM25 Levels
Grouped by Rural/Urban
pct_chg_aug %>%
na.omit() %>%
inner_join(., subset_glass, by = c('zcta' = 'zcta', 'week' = 'date')) %>%
select(zcta, fire_cat, week, PM25, wf_pm25_imp, bins, pct_chg_mon_z, Rural_Dummy_R) %>%
group_by(week,zcta) %>%
arrange(zcta) %>%
ggplot(data = ., aes(x = week, y = PM25,
color = Rural_Dummy_R)) +
geom_point(aes(color = Rural_Dummy_R), alpha = .5) +
scale_color_manual(values=c('Blue','Green')) +
geom_smooth(se = F) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +
labs(title="PM25 Values by Date and Rural Status") +
labs(x="Date", y="PM25 Values") +
labs(color='Nation') +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = 0, ymax = 100 ,
alpha = 0, color= "orange") + facet_wrap(vars(fire_cat), nrow = 3)

Grouped by Agricultural
pct_chg_aug %>%
na.omit() %>%
inner_join(., subset_glass, by = c('zcta' = 'zcta', 'week' = 'date')) %>%
select(zcta, fire_cat, week, PM25, wf_pm25_imp, bins, pct_chg_mon_z, Agr_Dummy_75) %>%
group_by(week,zcta) %>%
arrange(zcta) %>%
ggplot(data = ., aes(x = week, y = PM25,
color = Agr_Dummy_75)) +
geom_point(aes(color = Agr_Dummy_75), alpha = .5) +
scale_color_manual(values=c('Blue','Green')) +
geom_smooth(se = F) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +
labs(title="PM25 Values by Date and Industry") +
labs(x="Date", y="PM25 Values") +
labs(color='Nation') +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = 0, ymax = 100 ,
alpha = 0, color= "orange") + facet_wrap(vars(fire_cat), nrow = 3)

Grouped by Poverty
pct_chg_aug %>%
na.omit() %>%
inner_join(., subset_glass, by = c('zcta' = 'zcta', 'week' = 'date')) %>%
select(zcta, fire_cat, week, PM25, wf_pm25_imp, bins, pct_chg_mon_z, Poverty_Dummy_75) %>%
group_by(week,zcta) %>%
arrange(zcta) %>%
ggplot(data = ., aes(x = week, y = PM25,
color = Poverty_Dummy_75)) +
geom_point(aes(color = Poverty_Dummy_75), alpha = .5) +
scale_color_manual(values=c('Blue','Green')) +
geom_smooth(se = F) +
scale_x_date(breaks = "1 week", limits = as.Date(c("2020-08-31", "2020-10-12"))) +
labs(title="PM25 Values by Date and Poverty Status") +
labs(x="Date", y="PM25 Values") +
labs(color='Nation') +
annotate("rect", xmin = as.Date("2020-09-21"), xmax = as.Date("2020-10-12"),
ymin = 0, ymax = 100 ,
alpha = 0, color= "orange") + facet_wrap(vars(fire_cat), nrow = 3)

LS0tCnRpdGxlOiAiU2FmZUdyYXBoIE1vYmlsaXR5IEVEQSBNYXJrZG93biIKYXV0aG9yOiAiQW5kcmV3IExhaSIKZGF0ZTogIjMwLzA0LzIwMjIiCm91dHB1dDogICAKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdGhlbWU6IHNwYWNlbGFiCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCgojIyBSZWFkIGluIFNjcmlwdApgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQpzb3VyY2UoIlNhZmVncmFwaF9TY3JpcHQuUiIpCmBgYAoKYGBge3J9CnJtKGxpc3Q9bHMoKVshIGxzKCkgJWluJSBjKCJydXJhbF9pcHVtcyIsInJ1Y2EiLCAic3Vic2V0X2dsYXNzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3ZlcnR5X2lwdW1zIiwgInBjdF9jaGdfYXVnIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbmR1c3RyeV9pcHVtcyIsICJhdWdfY29tYmluZWQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZmZlcjFfdmVjIiwiYnVmZmVyMl9wZXJpbV92ZWMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZmZlcjJfdmVjIiwgImNmX2JmMSIsICJjZl9iZjIiLCAiZ2ZwZXJpbXZlYyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3RfemN0YSIsICJydXJhbF9ydWNhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICclbm90aW4lJywgJ3BwMScsICdwcDInLCAnYXVnX2NvbWJpbmVkJywgJ2NvbScpXSkKYGBgCgojIyBSZWFkIGluIFNwYXRpYWwgUGxvdHMKYGBge3J9CnBsb3QubmV3KCkgCnJhc3RlckltYWdlKHBwMSwwLDAsMSwxKQpgYGAKCgpgYGB7cn0KcGxvdC5uZXcoKSAKcmFzdGVySW1hZ2UocHAyLDAsMCwxLDEpCmBgYApJbml0aWFsbHkgYSBzaW5nbGUgMjAtYWNyZSBicnVzaCBmaXJlLCBpdCByYXBpZGx5IGdyZXcgYW5kIG1lcmdlZCB3aXRoIHR3byBzbWFsbGVyIGZpcmVzIHRoYXQgZXhwYW5kZWQgdG8gMTEsMDAwIGFjcmVzIGR1cmluZyB0aGUgbmlnaHQgb2YgU2VwdGVtYmVyIDI3IGludG8gU2VwdGVtYmVyIDI4LgoKVGhlIEdsYXNzIEZpcmUgd2FzIGZ1bGx5IGNvbnRhaW5lZCBvbiBPY3RvYmVyIDIwLCAyMDIwLCBhZnRlciBidXJuaW5nIG92ZXIgNjcsNDg0IGFjcmVzIGFuZCBkZXN0cm95aW5nIDEsNTU1IHN0cnVjdHVyZXMsIGluY2x1ZGluZyAzMDggaG9tZXMgYW5kIDM0MyBjb21tZXJjaWFsIGJ1aWxkaW5ncyBpbiBOYXBhIENvdW50eSwgYXMgd2VsbCBhcyAzMzQgaG9tZXMgaW4gU29ub21hIENvdW50eQoKCgojIyBEYXRhIFRhYmxlcyAoRGVzY3JpcHRpdmVzKQoKCkZpcmUgQ2F0ZWdvcnkgfCBUb3RhbCBaQ1RBCi0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tCkdGICAgICAgICAgICAgfCA4CkJGMSAgICAgICAgICAgfCAxNwpCRjIgICAgICAgICAgIHwgMTAKCgpVc2luZyBzaGFwZSBmaWxlcyBmcm9tIHRoZSBHbGFzc0ZpcmUsIDEwIGttIGJ1ZmZlcnMgd2VyZSB1c2VkIHRvIGNyZWF0ZSB0aGUgZmlyc3QgYnVmZmVyIChCRjEpLCAxMGttIHN1cnJvdW5kaW5nIEJGMSBjcmVhdGVzIHRoZSBzZWNvbmQgYnVmZmVyIChCRjIpLgoKRWFjaCBwZXJpbWV0ZXIgaGFzIHVuaXF1ZSBaQ1RBIHRoYXQgaXMgZXhjbHVzaXZlIHRvIHRoZWlyIHBlcmltZXRlci4gIAoKCmBgYHtyfQpEVDo6ZGF0YXRhYmxlKGNvbSAlPiUKICAgICAgICAgICAgICAgIGZpbHRlcihqdW5lICE9ICdKdW5lJykgJT4lCiAgICAgICAgICAgICAgICBtdXRhdGUobmV3X2RhdGUgPSBhcy5QT1NJWGN0KHN0cnB0aW1lKGRhdGVfcmFuZ2Vfc3RhcnQsICIlWS0lbS0lZCIpKSkgJT4lCiAgICAgICAgICAgICAgICBtdXRhdGUod2VlayA9IGFzX2RhdGUobmV3X2RhdGUpKSAlPiUKICAgICAgICAgICAgICAgIGdyb3VwX2J5KGNpdHksIHpjdGEsIHdlZWssIGZpcmVfY2F0LCAKICAgICAgICAgICAgICAgICAgICAgICAgIFBvdmVydHlfRHVtbXlfNzUsIEFncl9EdW1teV83NSwKICAgICAgICAgICAgICAgICAgICAgICAgIFJ1cmFsX0R1bW15X1IpICU+JQogICAgICAgICAgICAgICAgc3VtbWFyaXplKHN1bV92aXNpdCA9IHN1bShyYXdfdmlzaXRfY291bnRzKSwgLmdyb3VwcyA9ICdkcm9wJyksIAogICAgICAgICAgICAgIGNhcHRpb24gPSAnRGVzY3JpcHRpdmUgU3RhdGlzdGljcyBvZiBBdWd1c3QgTW9iaWxpdHknLCAKICAgICAgICAgICAgICBmaWx0ZXIgPSAidG9wIiwKICAgICAgICAgICAgICBleHRlbnNpb25zID0gYygiU2VhcmNoUGFuZXMiLCAiU2VsZWN0IiwgIkJ1dHRvbnMiKSwKICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChkb20gPSAiQnRpcCIsYnV0dG9ucyA9IGxpc3QoInNlYXJjaFBhbmVzIikpKQpgYGAKCgpgYGB7cn0KRFQ6OmRhdGF0YWJsZShjb20gJT4lCiAgICAgICAgICAgICAgICBmaWx0ZXIoanVuZSA9PSAnSnVuZScpICU+JQogICAgICAgICAgICAgICAgbXV0YXRlKG5ld19kYXRlID0gYXMuUE9TSVhjdChzdHJwdGltZShkYXRlX3JhbmdlX3N0YXJ0LCAiJVktJW0tJWQiKSkpICU+JQogICAgICAgICAgICAgICAgbXV0YXRlKHdlZWsgPSBhc19kYXRlKG5ld19kYXRlKSkgJT4lCiAgICAgICAgICAgICAgICBncm91cF9ieShjaXR5LCB6Y3RhLCB3ZWVrLCBmaXJlX2NhdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBQb3ZlcnR5X0R1bW15Xzc1LCBBZ3JfRHVtbXlfNzUsCiAgICAgICAgICAgICAgICAgICAgICAgICBSdXJhbF9EdW1teV9SKSAgJT4lCiAgICAgICAgICAgICAgc3VtbWFyaXplKHN1bV92aXNpdCA9IHN1bShyYXdfdmlzaXRfY291bnRzKSwgLmdyb3VwcyA9ICdkcm9wJyksIAogICAgICAgICAgICAgIGNhcHRpb24gPSAnRGVzY3JpcHRpdmUgU3RhdGlzdGljcyBvZiBKdW5lIE1vYmlsaXR5JywgCiAgICAgICAgICAgICAgZmlsdGVyID0gInRvcCIsCiAgICAgICAgICAgICAgZXh0ZW5zaW9ucyA9IGMoIlNlYXJjaFBhbmVzIiwgIlNlbGVjdCIsICJCdXR0b25zIiksCiAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3QoZG9tID0gIkJ0aXAiLGJ1dHRvbnMgPSBsaXN0KCJzZWFyY2hQYW5lcyIpKSkKYGBgCgojIyBWaXN1YWxpemF0aW9ucwoKCiMjIyBQZXJjZW50IENoYW5nZSBVc2luZyBGaXJlIENhdGVnb3J5IGFuZCBKdW5lIGFzIEJhc2VsaW5lCgoKYGBge3J9CnBjdF9jaGdfYXVnICU+JQogIG5hLm9taXQoKSAlPiUKICBncm91cF9ieSh3ZWVrLHpjdGEsZmlyZV9jYXQpICU+JQogIHN1bW1hcml6ZShtZWQgPSBtZWRpYW4ocGN0X2NoZ19tb25fZiksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGdncGxvdChkYXRhID0uLCBhZXMoeCA9IHdlZWssIHkgPSBtZWQsIGdyb3VwID0gemN0YSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicsICdSZWQnKSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyPWZpcmVfY2F0KSwgYWxwaGEgPSAwLjIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmaXJlX2NhdCksIGFscGhhID0gMC44KSArCiAgeWxpbSgtNTAsMjAwKSArCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIHdlZWsiLCBsaW1pdHMgPSBhcy5EYXRlKGMoIjIwMjAtMDgtMzEiLCAiMjAyMC0xMC0xMiIpKSkgKyMgd2VlayBvZiBPY3QgMTIKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIAogIGxhYnMoeD0iRGF0ZSIsIHk9Ik1lZGlhbiBQZXJjZW50IENoYW5nZSAoRGl2aWRlIGJ5IDEwMCkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpICArCiAgICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSBhcy5EYXRlKCIyMDIwLTA5LTIxIiksIHhtYXggPSBhcy5EYXRlKCIyMDIwLTEwLTEyIiksIAogICAgICAgICAgIHltaW4gPSAtNTAuMDAsIHltYXggPSAxNTAuMDAgLAogICAgICAgICAgICAgYWxwaGEgPSAwLCBjb2xvcj0gIm9yYW5nZSIpICsKICBnZ3RpdGxlKCJQZXJjZW50IENoYW5nZSBNb2JpbGl0eSBieSBGaXJlIENhdGVnb3J5IikKYGBgCgpXaGVuIGxvb2tpbmcgYXQgbW9iaWxpdHk6CiAgKyBXZWVrIG9mIEp1bmUgNiwgMjAyMCB0byB0aGUgd2VlayBvZiBKdW5lIDIyLCAyMDIwIGlzIHVzZWQgYXMgYSBiYXNlbGluZQogICsgUGVyY2VudCBjaGFuZ2UgaXMgY2FsY3VsYXRlZCBieSB3ZWVrIHRvIHdlZWsgaW4gZWFjaCBjb25zZWN1dGl2ZSB3ZWVrIGluIEp1bmUgCiAgKyBUaGUgbWVkaWFuIG9mIHBlcmNlbnQgY2hhbmdlIGlzIHRoZW4gZ3JvdXBlZCBieSBmaXJlIGNhdGVnb3J5IGluIEp1bmUgYW5kIGlzIHRoZW4gb2ZmaWNpYWxseSB0aGUKICBiYXNlbGluZSBmb3IgQXVndXN0IG1vYmlsaXR5CiAgKyBUaGVuIHRoZSBwZXJjZW50IGNoYW5nZSBvZiBBdWd1c3QgaXMgdGhlbiB1c2VkIGZvciBlYWNoIGNvbnNlY3V0aXZlIHdlZWsgaW4gQXVndXN0IChBdWd1c3QgMzEgLSBPY3RvYmVyIDEyKQogICsgQSBjYWxjdWxhdGlvbiBvZiBwZXJjZW50IGNoYW5nZSBpcyB0YWtlbiBieSB1c2luZyB0aGUgd2Vla2x5IHBlcmNlbnRhZ2UgY2hhbmdlIGZvciBBdWd1c3QgaW4gcmVsYXRpb24gdG8gdGhlIGZpcmUgY2F0ZWdvcnkgbWVkaWFuIHBlcmNlbnQgY2hhbmdlLiAgCgoKCkZpcmUgQ2F0ZWdvcnkgfCBNZWRpYW4gUGVyY2VudCBDaGFuZ2UKLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0KR0YgICAgICAgICAgICB8IDAuMDIKQkYxICAgICAgICAgICB8IDAuMDMKQkYyICAgICAgICAgICB8IDAuMDQKCgoKIyMjIFBlcmNlbnQgQ2hhbmdlIG9mIE1vYmlsaXR5IGJ5IFJ1cmFsLyBGaXJlIENhdGVnb3J5IGFuZCBKdW5lIGFzIEJhc2VsaW5lCgpSdXJhbCBDYXRlZ29yeSB8IFRvdGFsIFpDVEEKLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0KUnVyYWwgICAgICAgICB8IDExClVyYmFuICAgICAgICAgfCAyNAoKYGBge3J9CnBjdF9jaGdfYXVnICU+JQogIG5hLm9taXQoKSAlPiUKICBncm91cF9ieSh3ZWVrLHpjdGEsUnVyYWxfRHVtbXlfUiwgZmlyZV9jYXQpICU+JQogIHN1bW1hcml6ZShtZWQgPSBtZWRpYW4ocGN0X2NoZ19tb25fZiksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGdncGxvdChkYXRhID0uLCBhZXMoeCA9IHdlZWssIHkgPSBtZWQsIGdyb3VwID0gemN0YSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicsICdSZWQnKSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyPVJ1cmFsX0R1bW15X1IpLCBhbHBoYSA9IDAuMikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IFJ1cmFsX0R1bW15X1IpLCBhbHBoYSA9IDAuOCkgKwogIHlsaW0oLTUwLDIwMCkgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICsjIHdlZWsgb2YgT2N0IDEyCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSkgKyAKICBsYWJzKHg9IkRhdGUiLCB5PSJNZWRpYW4gUGVyY2VudCBDaGFuZ2UgKERpdmlkZSBieSAxMDApIikgKyAKICBmYWNldF93cmFwKHZhcnMoZmlyZV9jYXQpLCBucm93ID0gMykgKwogIGdndGl0bGUoIlBlcmNlbnQgQ2hhbmdlIE1vYmlsaXR5IGJ5IEZpcmUgQ2F0ZWdvcnkgYW5kIFJ1cmFsIikKYGBgCgoKYGBge3J9CnBjdF9jaGdfYXVnICU+JQogIG5hLm9taXQoKSAlPiUKICBncm91cF9ieSh3ZWVrLHpjdGEsIGZpcmVfY2F0KSAlPiUKICBncm91cF9ieShSdXJhbF9EdW1teV9SLCB3ZWVrLCBmaXJlX2NhdCkgJT4lCiAgc3VtbWFyaXplKG1lZCA9IG1lZGlhbihwY3RfY2hnX21vbl9mKSwgLmdyb3VwcyA9J2Ryb3AnKSAlPiUKICBnZ3Bsb3QoZGF0YSA9LiwgYWVzKHggPSB3ZWVrLCB5ID0gbWVkLCBncm91cCA9IFJ1cmFsX0R1bW15X1IpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nLCAnUmVkJykpICsKICBnZW9tX2xpbmUoYWVzKGNvbG91cj1SdXJhbF9EdW1teV9SKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgd2VlayIsIGxpbWl0cyA9IGFzLkRhdGUoYygiMjAyMC0wOC0zMSIsICIyMDIwLTEwLTEyIikpKSAgKyMgd2VlayBvZiBPY3QgMTIKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIGZhY2V0X3dyYXAodmFycyhmaXJlX2NhdCksIG5yb3cgPSAzKSAreWxpbSgtNTAsNTApICsKICBnZ3RpdGxlKCJQZXJjZW50IENoYW5nZSBNb2JpbGl0eSBieSBGaXJlIENhdGVnb3J5IGFuZCBSdXJhbCAoQ29sbGFwc2VkKSIpICsKICBsYWJzKHg9IkRhdGUiLCB5PSJNZWRpYW4gUGVyY2VudCBDaGFuZ2UgKERpdmlkZSBieSAxMDApIikgCmBgYAoKYGBge3J9CnBjdF9jaGdfYXVnICU+JQogIG5hLm9taXQoKSAlPiUKICBncm91cF9ieSh3ZWVrLHpjdGEpICU+JQogIGdyb3VwX2J5KFJ1cmFsX0R1bW15X1IsIHdlZWssIGZpcmVfY2F0KSAlPiUKICBmaWx0ZXIoZmlyZV9jYXQgPT0gJ0dGJykgJT4lCiAgc3VtbWFyaXplKG1lZCA9IG1lZGlhbihwY3RfY2hnX21vbl9mKSwgLmdyb3VwcyA9J2Ryb3AnKSAlPiUKICBnZ3Bsb3QoZGF0YSA9LiwgYWVzKHggPSB3ZWVrLCB5ID0gbWVkLCBncm91cCA9IFJ1cmFsX0R1bW15X1IpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nLCAnUmVkJykpICsKICBnZW9tX2xpbmUoYWVzKGNvbG91cj1SdXJhbF9EdW1teV9SKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgd2VlayIsIGxpbWl0cyA9IGFzLkRhdGUoYygiMjAyMC0wOC0zMSIsICIyMDIwLTEwLTEyIikpKSArIyB3ZWVrIG9mIE9jdCAxMgogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpICsgCiAgbGFicyh4PSJEYXRlIiwgeT0iTWVkaWFuIFBlcmNlbnQgQ2hhbmdlIChEaXZpZGUgYnkgMTAwKSIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkgICsKICAgIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IGFzLkRhdGUoIjIwMjAtMDktMjEiKSwgeG1heCA9IGFzLkRhdGUoIjIwMjAtMTAtMTIiKSwgCiAgICAgICAgICAgeW1pbiA9IC0yMCwgeW1heCA9IDYwICwKICAgICAgICAgICAgIGFscGhhID0gMCwgY29sb3I9ICJvcmFuZ2UiKSArCiAgZ2d0aXRsZSgiTWVkaWFuIFJhdyBWaXNpdHMgYnkgRGF0ZSAoR0YvQ29sbGFwc2VkKSIpCmBgYAoKCgojIyMgUGVyY2VudCBDaGFuZ2Ugb2YgTW9iaWxpdHkgYnkgQWdyaWN1bHR1cmUvIEZpcmUgQ2F0ZWdvcnkgYW5kIEp1bmUgYXMgQmFzZWxpbmUKCgpBZ3IgQ2F0ZWdvcnkgICB8IFRvdGFsIFpDVEEKLS0tLS0tLS0tLS0tLSAgfCAtLS0tLS0tLS0tLS0tCkFncjw3NSAgICAgICAgIHwgMjYKQWdyPjc1ICAgICAgICAgfCA5CgpgYGB7cn0KcGN0X2NoZ19hdWcgJT4lCiAgbmEub21pdCgpICU+JQogIGdyb3VwX2J5KHdlZWssemN0YSxBZ3JfRHVtbXlfNzUsIGZpcmVfY2F0KSAlPiUKICBzdW1tYXJpemUobWVkID0gbWVkaWFuKHBjdF9jaGdfbW9uX2YpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUKICBnZ3Bsb3QoZGF0YSA9LiwgYWVzKHggPSB3ZWVrLCB5ID0gbWVkLCBncm91cCA9IHpjdGEpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nLCAnUmVkJykpICsKICBnZW9tX2xpbmUoYWVzKGNvbG91cj1BZ3JfRHVtbXlfNzUpLCBhbHBoYSA9IDAuMikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IEFncl9EdW1teV83NSksIGFscGhhID0gMC44KSArCiAgeWxpbSgtNTAsMjAwKSArCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIHdlZWsiLCBsaW1pdHMgPSBhcy5EYXRlKGMoIjIwMjAtMDgtMzEiLCAiMjAyMC0xMC0xMiIpKSkgKyMgd2VlayBvZiBPY3QgMTIKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIAogIGxhYnMoeD0iRGF0ZSIsIHk9Ik1lZGlhbiBQZXJjZW50IENoYW5nZSAoRGl2aWRlIGJ5IDEwMCkiKSArIAogIGZhY2V0X3dyYXAodmFycyhmaXJlX2NhdCksIG5yb3cgPSAzKSArIAogIGdndGl0bGUoIlBlcmNlbnQgQ2hhbmdlIE1vYmlsaXR5IGJ5IEZpcmUgQ2F0ZWdvcnkgYW5kIEFnciBJbmR1c3RyeSIpCmBgYAoKYGBge3J9CiMgQWdyaWN1bHR1cmUgQlkgRmlyZSBDYXQKcGN0X2NoZ19hdWcgJT4lCiAgbmEub21pdCgpICU+JQogIGdyb3VwX2J5KHdlZWssemN0YSwgZmlyZV9jYXQpICU+JQogIGdyb3VwX2J5KEFncl9EdW1teV83NSwgd2VlaywgZmlyZV9jYXQpICU+JQogIHN1bW1hcml6ZShtZWQgPSBtZWRpYW4ocGN0X2NoZ19tb25fZiksIC5ncm91cHMgPSdkcm9wJykgJT4lCiAgZ2dwbG90KGRhdGEgPS4sIGFlcyh4ID0gd2VlaywgeSA9IG1lZCwgZ3JvdXAgPSBBZ3JfRHVtbXlfNzUpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nLCAnUmVkJykpICsKICBnZW9tX2xpbmUoYWVzKGNvbG91cj1BZ3JfRHVtbXlfNzUpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMikgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICArIyB3ZWVrIG9mIE9jdCAxMgoKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIGZhY2V0X3dyYXAodmFycyhmaXJlX2NhdCksIG5yb3cgPSAzKSAreWxpbSgtNTAsNTApICsKICBnZ3RpdGxlKCJQZXJjZW50IENoYW5nZSBNb2JpbGl0eSBieSBGaXJlIENhdGVnb3J5IGFuZCBBZ3IgKENvbGxhcHNlZCkiKSArIAogIGxhYnMoeD0iRGF0ZSIsIHk9Ik1lZGlhbiBQZXJjZW50IENoYW5nZSAoRGl2aWRlIGJ5IDEwMCkiKSAKYGBgCgoKCmBgYHtyfQpwY3RfY2hnX2F1ZyAlPiUKICBuYS5vbWl0KCkgJT4lCiAgZ3JvdXBfYnkod2Vlayx6Y3RhKSAlPiUKICBncm91cF9ieShBZ3JfRHVtbXlfNzUsIHdlZWssIGZpcmVfY2F0KSAlPiUKICBmaWx0ZXIoZmlyZV9jYXQgPT0gJ0dGJykgJT4lCiAgc3VtbWFyaXplKG1lZCA9IG1lZGlhbihwY3RfY2hnX21vbl9mKSwgLmdyb3VwcyA9J2Ryb3AnKSAlPiUKICBnZ3Bsb3QoZGF0YSA9LiwgYWVzKHggPSB3ZWVrLCB5ID0gbWVkLCBncm91cCA9IEFncl9EdW1teV83NSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicsICdSZWQnKSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyPUFncl9EdW1teV83NSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIHdlZWsiLCBsaW1pdHMgPSBhcy5EYXRlKGMoIjIwMjAtMDgtMzEiLCAiMjAyMC0xMC0xMiIpKSkgKyMgd2VlayBvZiBPY3QgMTIKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIAogIGxhYnMoeD0iRGF0ZSIsIHk9Ik1lZGlhbiBQZXJjZW50IENoYW5nZSAoRGl2aWRlIGJ5IDEwMCkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpICArCiAgICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSBhcy5EYXRlKCIyMDIwLTA5LTIxIiksIHhtYXggPSBhcy5EYXRlKCIyMDIwLTEwLTEyIiksIAogICAgICAgICAgIHltaW4gPSAtMjAsIHltYXggPSA2MCAsCiAgICAgICAgICAgICBhbHBoYSA9IDAsIGNvbG9yPSAib3JhbmdlIikrCiAgZ2d0aXRsZSgiTWVkaWFuIFJhdyBWaXNpdHMgYnkgRGF0ZSAoR0YvQ29sbGFwc2VkKSIpCmBgYAoKCgojIyMgUGVyY2VudCBDaGFuZ2Ugb2YgTW9iaWxpdHkgYnkgUG92ZXJ0eS8gRmlyZSBDYXRlZ29yeSBhbmQgSnVuZSBhcyBCYXNlbGluZQoKClBvdiBDYXRlZ29yeSAgIHwgVG90YWwgWkNUQQotLS0tLS0tLS0tLS0tICB8IC0tLS0tLS0tLS0tLS0KUG92PDc1ICAgICAgICAgfCAyNgpQb3Y+NzUgICAgICAgICB8IDkKCgoKCmBgYHtyfQpwY3RfY2hnX2F1ZyAlPiUKICBuYS5vbWl0KCkgJT4lCiAgZ3JvdXBfYnkod2Vlayx6Y3RhLFBvdmVydHlfRHVtbXlfNzUsIGZpcmVfY2F0KSAlPiUKICBzdW1tYXJpemUobWVkID0gbWVkaWFuKHBjdF9jaGdfbW9uX2YpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUKICBnZ3Bsb3QoZGF0YSA9LiwgYWVzKHggPSB3ZWVrLCB5ID0gbWVkLCBncm91cCA9IHpjdGEpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nLCAnUmVkJykpICsKICBnZW9tX2xpbmUoYWVzKGNvbG91cj1Qb3ZlcnR5X0R1bW15Xzc1KSwgYWxwaGEgPSAwLjIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBQb3ZlcnR5X0R1bW15Xzc1KSwgYWxwaGEgPSAwLjgpICsKICB5bGltKC01MCwyMDApICsKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgd2VlayIsIGxpbWl0cyA9IGFzLkRhdGUoYygiMjAyMC0wOC0zMSIsICIyMDIwLTEwLTEyIikpKSArIyB3ZWVrIG9mIE9jdCAxMgogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpICsgCiAgbGFicyh4PSJEYXRlIiwgeT0iTWVkaWFuIFBlcmNlbnQgQ2hhbmdlIChEaXZpZGUgYnkgMTAwKSIpICsgCiAgZmFjZXRfd3JhcCh2YXJzKGZpcmVfY2F0KSwgbnJvdyA9IDMpICsgCiAgZ2d0aXRsZSgiUGVyY2VudCBDaGFuZ2UgTW9iaWxpdHkgYnkgRmlyZSBDYXRlZ29yeSBhbmQgUG92ZXJ0eSBTdGF0dXMiKQpgYGAKCmBgYHtyfQojIFBvdmVydHkgQlkgRmlyZSBDYXQKcGN0X2NoZ19hdWcgJT4lCiAgbmEub21pdCgpICU+JQogIGdyb3VwX2J5KHdlZWssemN0YSwgZmlyZV9jYXQpICU+JQogIGdyb3VwX2J5KFBvdmVydHlfRHVtbXlfNzUsIHdlZWssIGZpcmVfY2F0KSAlPiUKICBzdW1tYXJpemUobWVkID0gbWVkaWFuKHBjdF9jaGdfbW9uX2YpLCAuZ3JvdXBzID0nZHJvcCcpICU+JQogIGdncGxvdChkYXRhID0uLCBhZXMoeCA9IHdlZWssIHkgPSBtZWQsIGdyb3VwID0gUG92ZXJ0eV9EdW1teV83NSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicsICdSZWQnKSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyPVBvdmVydHlfRHVtbXlfNzUpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMikgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICArIyB3ZWVrIG9mIE9jdCAxMgoKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIAogIGZhY2V0X3dyYXAodmFycyhmaXJlX2NhdCksIG5yb3cgPSAzKSArIHlsaW0oLTc1LDEwMCkgKwogIGxhYnMoeD0iRGF0ZSIsIHk9Ik1lZGlhbiBQZXJjZW50IENoYW5nZSAoRGl2aWRlIGJ5IDEwMCkiKSArIAogIGdndGl0bGUoIlBlcmNlbnQgQ2hhbmdlIE1vYmlsaXR5IGJ5IEZpcmUgQ2F0ZWdvcnkgYW5kIFBvdiAoQ29sbGFwc2VkKSIpIApgYGAKCgpgYGB7cn0KcGN0X2NoZ19hdWcgJT4lCiAgbmEub21pdCgpICU+JQogIGdyb3VwX2J5KHdlZWssemN0YSkgJT4lCiAgZ3JvdXBfYnkoUG92ZXJ0eV9EdW1teV83NSwgd2VlaywgZmlyZV9jYXQpICU+JQogIGZpbHRlcihmaXJlX2NhdCA9PSAnR0YnKSAlPiUKICBzdW1tYXJpemUobWVkID0gbWVkaWFuKHBjdF9jaGdfbW9uX2YpLCAuZ3JvdXBzID0nZHJvcCcpICU+JQogIGdncGxvdChkYXRhID0uLCBhZXMoeCA9IHdlZWssIHkgPSBtZWQsIGdyb3VwID0gUG92ZXJ0eV9EdW1teV83NSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicsICdSZWQnKSkgKwogIGdlb21fbGluZShhZXMoY29sb3VyPVBvdmVydHlfRHVtbXlfNzUpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMikgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICsjIHdlZWsgb2YgT2N0IDEyCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSkgKyAKICBsYWJzKHg9IkRhdGUiLCB5PSJNZWRpYW4gUGVyY2VudCBDaGFuZ2UgKERpdmlkZSBieSAxMDApIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSAgKwogICAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gYXMuRGF0ZSgiMjAyMC0wOS0yMSIpLCB4bWF4ID0gYXMuRGF0ZSgiMjAyMC0xMC0xMiIpLCAKICAgICAgICAgICB5bWluID0gLTI1LCB5bWF4ID0gNjAgLAogICAgICAgICAgICAgYWxwaGEgPSAwLCBjb2xvcj0gIm9yYW5nZSIpICsKICBndGl0bGUoIk1lZGlhbiBSYXcgVmlzaXRzIGJ5IERhdGUgKEdGL0NvbGxhcHNlZCkiKQpgYGAKCiMjIyBMb29raW5nIGF0IFBNMjUgTGV2ZWxzIAoKIyMjIyBHcm91cGVkIGJ5IFJ1cmFsL1VyYmFuCmBgYHtyfQpwY3RfY2hnX2F1ZyAlPiUKICBuYS5vbWl0KCkgJT4lCiAgaW5uZXJfam9pbiguLCBzdWJzZXRfZ2xhc3MsIGJ5ID0gYygnemN0YScgPSAnemN0YScsICd3ZWVrJyA9ICdkYXRlJykpICU+JQogIHNlbGVjdCh6Y3RhLCBmaXJlX2NhdCwgd2VlaywgUE0yNSwgd2ZfcG0yNV9pbXAsIGJpbnMsIHBjdF9jaGdfbW9uX3osIFJ1cmFsX0R1bW15X1IpICU+JQogIGdyb3VwX2J5KHdlZWssemN0YSkgJT4lCiAgYXJyYW5nZSh6Y3RhKSAlPiUKICBnZ3Bsb3QoZGF0YSA9IC4sIGFlcyh4ID0gd2VlaywgeSA9IFBNMjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBSdXJhbF9EdW1teV9SKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUnVyYWxfRHVtbXlfUiksIGFscGhhID0gLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicpKSArCiAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICsKICBsYWJzKHRpdGxlPSJQTTI1IFZhbHVlcyBieSBEYXRlIGFuZCBSdXJhbCBTdGF0dXMiKSArCiAgbGFicyh4PSJEYXRlIiwgeT0iUE0yNSBWYWx1ZXMiKSArCiAgbGFicyhjb2xvcj0nTmF0aW9uJykgICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSBhcy5EYXRlKCIyMDIwLTA5LTIxIiksIHhtYXggPSBhcy5EYXRlKCIyMDIwLTEwLTEyIiksIAogICAgICAgICAgIHltaW4gPSAwLCB5bWF4ID0gMTAwICwKICAgICAgICAgICAgIGFscGhhID0gMCwgY29sb3I9ICJvcmFuZ2UiKSAgKyBmYWNldF93cmFwKHZhcnMoZmlyZV9jYXQpLCBucm93ID0gMykKYGBgCgojIyMjIEdyb3VwZWQgYnkgQWdyaWN1bHR1cmFsCmBgYHtyfQpwY3RfY2hnX2F1ZyAlPiUKICBuYS5vbWl0KCkgJT4lCiAgaW5uZXJfam9pbiguLCBzdWJzZXRfZ2xhc3MsIGJ5ID0gYygnemN0YScgPSAnemN0YScsICd3ZWVrJyA9ICdkYXRlJykpICU+JQogIHNlbGVjdCh6Y3RhLCBmaXJlX2NhdCwgd2VlaywgUE0yNSwgd2ZfcG0yNV9pbXAsIGJpbnMsIHBjdF9jaGdfbW9uX3osIEFncl9EdW1teV83NSkgJT4lCiAgZ3JvdXBfYnkod2Vlayx6Y3RhKSAlPiUKICBhcnJhbmdlKHpjdGEpICU+JQogIGdncGxvdChkYXRhID0gLiwgYWVzKHggPSB3ZWVrLCB5ID0gUE0yNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IEFncl9EdW1teV83NSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IEFncl9EdW1teV83NSksIGFscGhhID0gLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJ0JsdWUnLCdHcmVlbicpKSArCiAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSB3ZWVrIiwgbGltaXRzID0gYXMuRGF0ZShjKCIyMDIwLTA4LTMxIiwgIjIwMjAtMTAtMTIiKSkpICsKICBsYWJzKHRpdGxlPSJQTTI1IFZhbHVlcyBieSBEYXRlIGFuZCBJbmR1c3RyeSIpICsKICBsYWJzKHg9IkRhdGUiLCB5PSJQTTI1IFZhbHVlcyIpICsKICBsYWJzKGNvbG9yPSdOYXRpb24nKSAgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IGFzLkRhdGUoIjIwMjAtMDktMjEiKSwgeG1heCA9IGFzLkRhdGUoIjIwMjAtMTAtMTIiKSwgCiAgICAgICAgICAgeW1pbiA9IDAsIHltYXggPSAxMDAgLAogICAgICAgICAgICAgYWxwaGEgPSAwLCBjb2xvcj0gIm9yYW5nZSIpICArIGZhY2V0X3dyYXAodmFycyhmaXJlX2NhdCksIG5yb3cgPSAzKQpgYGAKCgojIyMjIEdyb3VwZWQgYnkgUG92ZXJ0eQpgYGB7cn0KcGN0X2NoZ19hdWcgJT4lCiAgbmEub21pdCgpICU+JQogIGlubmVyX2pvaW4oLiwgc3Vic2V0X2dsYXNzLCBieSA9IGMoJ3pjdGEnID0gJ3pjdGEnLCAnd2VlaycgPSAnZGF0ZScpKSAlPiUKICBzZWxlY3QoemN0YSwgZmlyZV9jYXQsIHdlZWssIFBNMjUsIHdmX3BtMjVfaW1wLCBiaW5zLCBwY3RfY2hnX21vbl96LCBQb3ZlcnR5X0R1bW15Xzc1KSAlPiUKICBncm91cF9ieSh3ZWVrLHpjdGEpICU+JQogIGFycmFuZ2UoemN0YSkgJT4lCiAgZ2dwbG90KGRhdGEgPSAuLCBhZXMoeCA9IHdlZWssIHkgPSBQTTI1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gUG92ZXJ0eV9EdW1teV83NSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFBvdmVydHlfRHVtbXlfNzUpLCBhbHBoYSA9IC41KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCdCbHVlJywnR3JlZW4nKSkgKwogIGdlb21fc21vb3RoKHNlID0gRikgKyAKICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgd2VlayIsIGxpbWl0cyA9IGFzLkRhdGUoYygiMjAyMC0wOC0zMSIsICIyMDIwLTEwLTEyIikpKSArCiAgbGFicyh0aXRsZT0iUE0yNSBWYWx1ZXMgYnkgRGF0ZSBhbmQgUG92ZXJ0eSBTdGF0dXMiKSArCiAgbGFicyh4PSJEYXRlIiwgeT0iUE0yNSBWYWx1ZXMiKSArCiAgbGFicyhjb2xvcj0nTmF0aW9uJykgICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSBhcy5EYXRlKCIyMDIwLTA5LTIxIiksIHhtYXggPSBhcy5EYXRlKCIyMDIwLTEwLTEyIiksIAogICAgICAgICAgIHltaW4gPSAwLCB5bWF4ID0gMTAwICwKICAgICAgICAgICAgIGFscGhhID0gMCwgY29sb3I9ICJvcmFuZ2UiKSAgKyBmYWNldF93cmFwKHZhcnMoZmlyZV9jYXQpLCBucm93ID0gMykKYGBgCgo=